在一般的工作平行化處理中,可以透過 parallel
而起的兩個參數CI_NODE_INDEX
和 CI_NODE_TOTAL
做工作的分頁拆分,但因為參數僅止於是數字,對於不能透過參數設定拆分的工具來說,就相對的不實用了。那麼,輸入的參數可以自訂嗎?例如是一個陣列的變數?
假設我們有一個專案,區分為 32位元及 64位元版本,且驗證時,需要在不同的作業系統上確認。那麼,我們可能會有一個類似底下的 .gitlab-ci.yml
GitLab CI script:
stages:
- build
.build_template:
image: ${BUILD_OS}
stage: build
before_script:
- echo "prepare build env"
after_script:
- echo "clean up env"
script:
- echo "build ${BUILD_OS} ${PRODUCT_BIT} application"
build:ubuntu:20.04:32bit:
extends: .build_template
variables:
BUILD_OS: ubuntu:20.04
PRODUCT_BIT: 32bit
build:ubuntu:18.04:32bit:
extends: .build_template
variables:
BUILD_OS: ubuntu:18.04
PRODUCT_BIT: 32bit
build:ubuntu:20.04:64bit:
extends: .build_template
variables:
BUILD_OS: ubuntu:20.04
PRODUCT_BIT: 64bit
build:ubuntu:18.04:64bit:
extends: .build_template
variables:
BUILD_OS: ubuntu:18.04
PRODUCT_BIT: 64bit
上面的例子中。透過 BUILD_OS
及 PRODUCT_BIT
兩個變數來設定 .build_template
這個工作的參數,使 script
及 image
中可以透過參數的設定,進而取得對應所需的 image 及執行不同的結果。看起來似乎還蠻合理的,但當需要變更參數名稱,又或需要增加參數名稱的時候,對應出來的四個工作就都必須進行調整。
例如,這時候如果再次增加一個新的參數,這參數共有兩個數值必須要測試,那麼這個 GitLab CI script 展開就會變成 8 個工作,隨著參數增加又或增修參數,都會變成莫大的工作量。
在上一篇 Day17 中提到可以透過 parallel
產生出 CI_NODE_INDEX
和 CI_NODE_TOTAL
兩個環境變數來分頁拆分工作,如果這樣的拆分可以改為由人工設定的變數陣列,是不是就可以解決在上一段最後所提出的問題呢?因此 GitLab 在 13.3 版中,推出了 Parallel matrix jobs 的功能,透過 parallel matrix 的機制,就可以讓我們自己定義平行化工作的參數值,以上面的例子做調整,就可以修改為:
stages:
- build
build_template:
image: ${BUILD_OS}
stage: build
before_script:
- echo "prepare build env"
after_script:
- echo "clean up env"
script:
- echo "build ${BUILD_OS} ${PRODUCT_BIT} application"
parallel:
matrix:
- BUILD_OS: ['ubuntu:20.04', 'ubuntu:18.04']
PRODUCT_BIT: ['32bit', '64bit']
如上面的範例,其就可以達到與上一個例子中,同樣的效果,但所有的參數集中在同一個 JOB 之中。把 Script 加上 parallel matrix 的運用之後,無論是新增刪除參數,或調整一個參數名稱,也僅需要在同一個工作中作調整,對於 GitLab CI Script 的可維護性有明顯的的提升。
繼續延伸上面的例子,如果現在要執行的工作環境要再增加 CentOS 作業系統版本,但其對應的原是碼 PRODUCT_BIT
並非以 32bit 或 64bit 區分時,那可以怎麼設置?
stages:
- build
build_template:
image: ${BUILD_OS}
stage: build
before_script:
- echo "prepare build env"
after_script:
- echo "clean up env"
script:
- echo "build ${BUILD_OS} ${PRODUCT_BIT} application"
parallel:
matrix:
- BUILD_OS: ['ubuntu:20.04', 'ubuntu:18.04']
PRODUCT_BIT: ['32bit', '64bit']
- BUILD_OS: ['centos:7', 'centos:8']
PRODUCT_BIT: 'CentOS 64'
如上面的這例子,其透過 build_template
產出的工作就可以增加新的屬於 ARM
系統的對應,可拆解後的工作總共有 6 個,清單列表如下:
其流水線執行結果如下圖:
另外,陣列的放置,除了可以使用中括弧包裹外,也可以透過與 script 一樣,透過 -
符號來編輯陣列,如上面的例子,也可以改為:
stages:
- build
build_template:
image: ${BUILD_OS}
stage: build
before_script:
- echo "prepare build env"
after_script:
- echo "clean up env"
script:
- echo "build ${BUILD_OS} ${PRODUCT_BIT} application"
parallel:
matrix:
- BUILD_OS:
- 'ubuntu:20.04'
- 'ubuntu:18.04'
PRODUCT_BIT:
- '32bit'
- '64bit'
- BUILD_OS:
- 'centos:7'
- 'centos:8'
PRODUCT_BIT: 'CentOS 64'
透過 parallel matrix 的機制,讓原本必須要調整為多個工作的得以合併到一個工作之中,透過 parallel matrix 設定不一樣的參數,這讓 GitLab CI 的內容變得較容易維護,但必須要特別注意,目前 GitLab CI 將可拆分的平行化工作上限設置在 50 個,因此都有多參數的工作時,必須要特別計算,是否超過 50 個。
接下來,將繼續介紹關於 GitLab CI 的其他參數們;我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。